/**
 * - 作者: DoooReyn
 * - 日期: 2023.11.03
 */

import { _decorator, Color, EventTouch, Graphics, Node, tween, view } from 'cc';
import { app, ccclass, ccmodifier, Top } from '../../../extensions/cc-feather/assets/src';
import { LoggerComponent } from '../../../extensions/cc-feather/assets/src/components';
import { Manager } from '../../../extensions/cc-feather/assets/src/manager/Manager';
import { Pool, PoolObject } from '../../../extensions/wing/assets/src';

/**
 * - 名称: ClickEffect
 * - 描述: 点击特效
 */
@ccclass
@ccmodifier('ClickEffect')
class ClickEffect extends LoggerComponent implements PoolObject {
    /** 绘制组件 */
    private __graphics: Graphics;
    /** 触摸点 x 坐标 */
    private __x: number;
    /** 触摸点 y 坐标 */
    private __y: number;

    /** 随机通道色值 */
    private randomColorBit() {
        return (Math.random() * 256) | 0;
    }

    /** 随机颜色 */
    private randomColor() {
        return new Color(this.randomColorBit(), this.randomColorBit(), this.randomColorBit());
    }

    protected onEnable(): void {
        const { __x: x, __y: y } = this;
        const { width, height } = view.getVisibleSize();
        const xx = (x - width / 2) | 0;
        const yy = (y - height / 2) | 0;
        this.__graphics.clear();
        this.__graphics.strokeColor = this.randomColor();

        let data = { value: 0 };
        tween(data)
            .to(
                0.5,
                { value: 1 },
                {
                    onUpdate: (_: any, value: number) => {
                        this.__graphics.clear();
                        this.__graphics.circle(xx, yy, value * 32);
                        this.__graphics.stroke();
                    },
                    onComplete: () => {
                        MouseClicker.GetInstance().pool.put(this);
                        this.logger.debug('对象池剩余数量', MouseClicker.GetInstance().pool.size);
                    },
                }
            )
            .start();
    }

    protected onDestroy(): void {
        this.__graphics = null;
    }

    use(): void {
        this.__graphics = this.getComponent(Graphics);
        this.__graphics.clear();
        this.__graphics.lineWidth = 4;
    }

    recycle(): void {
        this.node.removeFromParent();
    }

    /**
     * 同步点击位置
     * @param x 触点 x 坐标
     * @param y 触点 y 坐标
     */
    click(x: number, y: number) {
        this.__x = x;
        this.__y = y;
    }
}

/**
 * - 名称: createClicker
 * - 描述: 点击特效创建工厂
 */
function createClicker() {
    const node = new Node('ClickEffect');
    node.addComponent(Graphics);
    return node.addComponent(ClickEffect);
}

/**
 * - 名称: MouseClicker
 * - 描述: 点击特效管理器
 */
export class MouseClicker extends Manager {
    /** 点击特效对象池 */
    public pool: Pool<ClickEffect>;

    public get uname(): string {
        return 'MouseClicker';
    }

    /** 屏幕被点击时调用 */
    protected onMouseClicked(e: EventTouch) {
        const effect = this.pool.get();
        const { x, y } = e.getUILocation();
        effect.click(x, y);
        app.view.top.node.addChild(effect.node);
        this.logger.debug('对象池剩余数量', this.pool.size);
    }

    protected async onInit(): Promise<void> {
        this.pool = new Pool<ClickEffect>(createClicker, 5);
        app.view.top.node.on(Top.EventType.TouchSceen, this.onMouseClicked, this);
    }

    protected async onDeinit(): Promise<void> {
        this.pool.clear();
        app.view.top.node.off(Top.EventType.TouchSceen, this.onMouseClicked, this);
    }
}
